<?php

namespace iBrand\Shop\Backend\Http\Controllers;

use Encore\Admin\Facades\Admin;
use Encore\Admin\Layout\Content;
use iBrand\Component\Goods\Models\Goods;
use iBrand\Component\Goods\Models\GoodsProduct;
use iBrand\Component\Goods\Models\Supplier;
use iBrand\Component\Goods\Repositories\GoodsProductRepository;
use iBrand\Component\Purchase\Models\StockRecord;
use iBrand\Component\Purchase\Models\TakeStock;
use iBrand\Component\Purchase\Repositories\StockRecordRepository;
use iBrand\Component\Purchase\Repositories\TakeStockItemRepository;
use iBrand\Component\Purchase\Repositories\TakeStockRepository;
use iBrand\Shop\Backend\Model\TakeStockPlan;
use iBrand\Shop\Backend\Repository\O2oGoodsProductsRepository;
use iBrand\Shop\Backend\Repository\O2oGoodsRepository;
use iBrand\Shop\Backend\Service\CommonService;
use iBrand\Shop\Core\Models\ClerkAdminRelation;
use iBrand\Shop\Core\Models\O2oGoodsProducts;
use iBrand\Shop\Core\Models\TakeStockPlanItems;
use iBrand\Shop\Core\Service\WarehouseService;
use Illuminate\Http\Request;
use Validator;
use DB;

class TakeStockController extends Controller
{
    protected $goodsProductRepository;
    protected $takeStockRepository;
    protected $takeStockItemRepository;
    protected $stockRecordRepository;
    protected $o2oGoodsRepository;
    protected $o2oGoodsProductsRepository;
    protected $commonService;
    protected $warehouseService;

    public function __construct(GoodsProductRepository $goodsProductRepository,
                                TakeStockRepository $takeStockRepository,
                                TakeStockItemRepository $takeStockItemRepository,
                                StockRecordRepository $stockRecordRepository,
                                O2oGoodsRepository $o2oGoodsRepository,
                                O2oGoodsProductsRepository $o2oGoodsProductsRepository,
                                CommonService $commonService,
                                WarehouseService $warehouseService)
    {
        $this->goodsProductRepository = $goodsProductRepository;
        $this->takeStockRepository = $takeStockRepository;
        $this->takeStockItemRepository = $takeStockItemRepository;
        $this->stockRecordRepository = $stockRecordRepository;
        $this->o2oGoodsRepository = $o2oGoodsRepository;
        $this->o2oGoodsProductsRepository = $o2oGoodsProductsRepository;
        $this->commonService = $commonService;
        $this->warehouseService = $warehouseService;
    }

    public function index()
    {
        $condition = $this->searchCondition();

        $lists = $this->takeStockRepository->getTakeStockPaginate($condition[0], $condition[1]);

        return Admin::content(function (Content $content) use ($lists) {
            $content->description('库存盘点');

            $content->breadcrumb(
                ['text' => '库存盘点', 'url' => '', 'no-pjax' => 1, 'left-menu-active' => '库存盘点']
            );

            return $content->body(view('shop-backend::takeStock.index', compact('lists')));
        });
    }

    private function searchCondition()
    {
        $where['shop_id'] = session('shop_id');
        $time = [];

        if (request('code')) {
            $where['code'] = request('code');
        }

        if (!empty(request('etime')) && !empty(request('stime'))) {
            $where['created_at'] = ['<=', request('etime')];
            $time['created_at'] = ['>=', request('stime')];
        }

        if (!empty(request('etime'))) {
            $time['created_at'] = ['<=', request('etime')];
        }

        if (!empty(request('stime'))) {
            $time['created_at'] = ['>=', request('stime')];
        }

        return [$where, $time];
    }

    public function create()
    {
        $plan_id = \request('plan_id');
        $suppliers = Supplier::where('status', 1)->get(['id', 'name', 'code'])->toArray();
        $specList = $this->commonService->getSpecList();
        $colors = $specList['colors'];
        $sizes = $specList['sizes'];
        $order_type = 'take_stock';
        $button_text = '盘点';

        return Admin::content(function (Content $content) use ($suppliers, $colors, $sizes, $order_type, $button_text, $plan_id) {
            $content->description('库存盘点单');

            $content->breadcrumb(
                ['text' => '库存盘点', 'url' => 'warehouse/take/stock', 'no-pjax' => 1],
                ['text' => '库存盘点单', 'url' => '', 'no-pjax' => 1, 'left-menu-active' => '库存盘点']
            );

            return $content->body(view('shop-backend::purchase.create', compact('suppliers', 'sizes', 'colors', 'order_type', 'button_text', 'plan_id')));
        });
    }

    public function show($id)
    {
        $takeStock = $this->takeStockRepository->find($id);

        return Admin::content(function (Content $content) use ($takeStock) {

            $content->header('盘点单详情');

            $content->breadcrumb(
                ['text' => '库存盘点', 'url' => 'warehouse/take/stock', 'no-pjax' => 1],
                ['text' => '库存盘点单', 'url' => '', 'no-pjax' => 1, 'left-menu-active' => '库存盘点']
            );

            $content->body(view('shop-backend::takeStock.show', compact('takeStock')));
        });
    }

    public function store(Request $request)
    {
        $order = $request->input('order');
        $order = json_decode($order, true);
        $goods = $request->input('goods');
        $goods = json_decode($goods, true);
        if (empty($goods) || empty($order)) {
            return $this->ajaxJson(false, [], 500, '请选择商品');
        }

        $goodsValidator = $this->validateGoods($goods);
        if ($goodsValidator->fails()) {

            return $this->ajaxJson(false, [], 500, $goodsValidator->messages()->first());
        }

        $goodsCollect = collect($goods);
        $shop_id = session('shop_id');
        try {
            DB::beginTransaction();
            $clerk = ClerkAdminRelation::where('admin_id', auth('admin')->user()->id)->first();

            $plan_id = isset($order['scene']) ? 0 : $order['plan_id'];  //这样做是因为如果的单品调整库存，不存在plan_id

            $stockData = [
                'shop_id' => $shop_id,
                'code' => 'TS' . date('YmdHis') . mt_rand(10000000, 99999999),
                'clerk_id' => $clerk ? $clerk->clerk_id : 0,
                'total' => $goodsCollect->sum('quantity'),
                'difference_count' => 0,
                'difference_amount' => 0,
                'remark' => $order['remark'],
                'plan_id' => $plan_id
            ];

            $takeStock = $this->takeStockRepository->create($stockData);

            foreach ($goods as $good) {
                $factory_price = isset($good['price']) ? $good['price'] : 0;
                if ($good['currentSku']) {
                    $product = $this->goodsProductRepository->getProductBySku($good['currentSku']);
                    $item_id = $product->id;
                    $item_type = GoodsProduct::class;

                    if (!$factory_price) {
                        $factory_price = $product->goods->factory_price;
                        $good['price'] = $factory_price;
                    }

                } else {
                    $item_id = $good['goods_id'];
                    $item_type = Goods::class;
                }


                $takeStockPlanItems = null;
                if ($plan_id AND !$takeStockPlanItems = TakeStockPlanItems::where('take_stock_plan_id', $plan_id)->where('base_product_id', $item_id)->first()) {
                    return $this->ajaxJson(false, [], 500, $good['goods_no'] . '  ' . $good['color'] . '  ' . $good['size'] . ' 不在本次盘点计划内');
                }

                if ($takeStockPlanItems AND $takeStockPlanItems->status == 1) continue;


                if (!$factory_price) {
                    return $this->ajaxJson(false, [], 500, '进货价不存在');
                }

                $this->warehouseService->addTakeStockItem($takeStock->id, $good, $item_id, $item_type);

                $this->warehouseService->addTakeStockRecord($shop_id, $takeStock->id, $good, $item_id, $item_type);

                $o2oGoods = $this->o2oGoodsRepository->findWhere(['status' => 1, 'goods_id' => $good['goods_id'], 'shop_id' => $shop_id])->first();

                $o2oGoodsId = $o2oGoods->id;

                $this->addO2oGoodsProduct($o2oGoodsId, $good, $item_id);

                $store_nums = O2oGoodsProducts::where('o2o_goods_id', $o2oGoodsId)->sum('store_nums');
                $o2oGoods->store_nums = $store_nums;
                $o2oGoods->save();

                if ($takeStockPlanItems) {
                    $takeStockPlanItems->status = 1;
                    $takeStockPlanItems->save();
                }
            }

            $difference_count = $takeStock->items()->sum('difference_count');
            $difference_amount = $takeStock->items()->sum('difference_amount');
            $takeStock->difference_count = $difference_count;
            $takeStock->difference_amount = $difference_amount;

            $takeStock->save();

            DB::commit();

            return $this->ajaxJson();
        } catch (\Exception $exception) {
            DB::rollBack();
            \Log::info($exception->getTraceAsString());
            \Log::info($exception->getMessage());
            return $this->ajaxJson(false, '', 500, $exception->getMessage());
        }
    }

    public function addO2oGoodsProduct($o2oGoodsId, $good, $product_id)
    {
        $shop_id = session('shop_id');
        $o2oGoodsProduct = $this->o2oGoodsProductsRepository->findWhere(['shop_id' => $shop_id, 'o2o_goods_id' => $o2oGoodsId, 'goods_id' => $good['goods_id'], 'product_id' => $product_id])->first();
        if ($o2oGoodsProduct) {
            $o2oGoodsProduct->store_nums = $good['quantity'];
            $o2oGoodsProduct->save();
        } else {
            /*$this->o2oGoodsProductsRepository->create([
                'goods_id' => $good['goods_id'],
                'o2o_goods_id' => $o2oGoodsId,
                'shop_id' => $shop_id,
                'product_id' => $product_id,
                'store_nums' => $good['quantity'],
            ]);*/
        }
    }

    public function validateGoods($goods)
    {
        $rules = [
            '*.goods_name' => 'required',
            '*.goods_no' => 'required',
            '*.goods_id' => 'required',
            '*.currentSku' => 'required',
            '*.color' => 'required',
            '*.color_id' => 'required',
            '*.size' => 'required',
            '*.size_id' => 'required',
            '*.beforeNumber' => 'required|integer|min:0',
            '*.quantity' => 'required|integer|min:0',
        ];

        $message = [
            "required" => ":attribute 不能为空",
            "integer" => ":attribute 必须是整数",
            "min" => ":attribute 必须大于等于0",
        ];

        $attributes = [
            '*.goods_name' => '商品名称',
            '*.goods_no' => '商品货号',
            '*.goods_id' => '商品id',
            '*.beforeNumber' => '盘点前数量',
            '*.quantity' => '盘点数量',
        ];

        $validator = Validator::make($goods, $rules, $message, $attributes);

        return $validator;
    }

    /**
     * 审核收银端提交的盘点数据，写入最终库存
     */
    public function reviewTake()
    {
        $shop_id = session('shop_id');
        $plan_id = request('plan_id');
        $page = request('page') ? request('page') : 1;

        $plan = TakeStockPlan::where(['id' => $plan_id, 'shop_id' => $shop_id])->first();
        $take_ids = $plan->takeStocks->pluck('id')->toArray();
        $where['take_stock_id'] = $take_ids;
        $where['status'] = 0;
        $lists = $this->takeStockItemRepository->getTakeStockItemsPaginate($where);
        $lastPage = $lists->lastPage();

        if ($lists->count()) {
            foreach ($lists as $list) {
                if ($list->status == 1) continue;

                $good = $list->meta;
                $good['quantity'] = $list->count;
                $good['currentSku'] = $good['sku'];

                $this->warehouseService->addTakeStockRecord($shop_id, $list->take_stock_id, $good, $list->item_id, $list->item_type);

                $o2oGoods = $this->o2oGoodsRepository->findWhere(['status' => 1, 'goods_id' => $good['goods_id'], 'shop_id' => $shop_id])->first();

                $this->addO2oGoodsProduct($o2oGoods->id, $good, $list->item_id);

                $store_nums = O2oGoodsProducts::where('o2o_goods_id', $o2oGoods->id)->sum('store_nums');
                $o2oGoods->store_nums = $store_nums;
                $o2oGoods->save();

                $list->status = 1;
                $list->save();
            }
        }

        if ($page == $lastPage) {
            return $this->ajaxJson(true, ['status' => 'complete']);
        }

        $url_bit = route('admin.shop.take.stock.reviewTake', array_merge(['page' => $page + 1], request()->except('page', 'limit')));

        return $this->ajaxJson(true, ['status' => 'goon', 'url' => $url_bit, 'current_page' => $page, 'totalPage' => $lastPage]);


    }

    public function reviewTakeModal()
    {
        $store_url = route('admin.shop.take.stock.reviewTake', ['plan_id' => \request('plan_id')]);
        return view('shop-backend::takeStock.review_modal', compact('store_url'));
    }
}